home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Skunkware 5
/
Skunkware 5.iso
/
src
/
X11
/
mfsm-1.1
/
mfsm.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-06-23
|
49KB
|
1,708 lines
/**
Motif File System Monitor - V 1.1
by
SDH EngSoft
(Shane D. Hill)
+-------------------------------------------------------------------+
| Copyright 1995 by Shane D. Hill (Shane.Hill@dsto.defence.gov.au) |
| |
| Permission to use, copy, modify, and to distribute this software |
| and its documentation for any purpose is hereby granted without |
| fee, provided that the above copyright notice appear in all |
| copies and that both that copyright notice and this permission |
| notice appear in supporting documentation. There is no |
| representations about the suitability of this software for |
| any purpose. this software is provided "as is" without express |
| or implied warranty. |
| |
+-------------------------------------------------------------------+
**/
/**
C Includes
**/
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/**
Motif Includes
**/
#include <Xm/CascadeB.h>
#include <Xm/DialogS.h>
#include <Xm/DrawingA.h>
#include <Xm/DrawnB.h>
#include <Xm/Form.h>
#include <Xm/Frame.h>
#include <Xm/Label.h>
#include <Xm/PanedW.h>
#include <Xm/PushB.h>
#include <Xm/RowColumn.h>
#include <Xm/Separator.h>
#include <Xm/Text.h>
#include <Xm/ToggleB.h>
#include <Xm/MwmUtil.h>
/**
System Includes
**/
#include <errno.h>
#include <pwd.h>
#include <sys/types.h>
#if defined(LINUX) || defined(SUNOS) || defined(HPUX)
# include <sys/vfs.h>
#elif defined(SOLARIS)
# include <sys/statvfs.h>
#elif defined(DIGITAL_UNIX)
# include <sys/mount.h>
#else
# include <sys/statfs.h>
#endif
#ifdef HAVE_QUOTAS
# if defined(AIX)
# include <jfs/quota.h>
# elif defined(DIGITAL_UNIX) || defined(SUNOS)
# include <ufs/quota.h> /** ufs is for SunOS 4.1.3 **/
/** # include <sys/fs/sfs_quota.h> /** sfs is for SVR4.2 **/
# elif defined(SOLARIS)
# include <sys/fs/ufs_quota.h>
# else
# include <sys/quota.h>
# endif
#endif /** HAVE QUOTAS **/
#ifdef USE_IOCTL
# include <fcntl.h>
#endif
/**
XPM Library & Pixmaps
**/
#ifdef HAVE_XPM
# include "xpm.h"
# include "bitmaps/floppydrive.xpm"
# include "bitmaps/diskdrive.xpm"
# include "bitmaps/netdrive.xpm"
# include "bitmaps/user.xpm"
# include "bitmaps/bell.xpm"
# include "bitmaps/nobell.xpm"
# include "bitmaps/mouse_help.xpm"
# include "bitmaps/about_mfsm.xpm"
# include "bitmaps/icon.xpm"
#endif
/**
X11 Bitmaps
**/
#include "bitmaps/floppydrive.xbm"
#include "bitmaps/diskdrive.xbm"
#include "bitmaps/netdrive.xbm"
#include "bitmaps/user.xbm"
#include "bitmaps/bell.xbm"
#include "bitmaps/nobell.xbm"
#include "bitmaps/mouse_help.xbm"
#include "bitmaps/about_mfsm.xbm"
#include "bitmaps/icon.xbm"
enum { FLOPPY_DISK,
HARD_DISK,
NETWORK_DISK,
USER,
BELL,
NOBELL,
MOUSE_HELP,
CDROM
};
enum { ABOUT,
ICONIC
};
enum { SYSTEM_SPACE,
QUOTA_SPACE
};
#ifdef HAVE_XPM
typedef struct icon_data {
Pixmap pixmap;
char **xpm_data;
char *bm_bits;
int bm_width;
int bm_height;
int mask;
} ICONS;
#else
typedef struct icon_data {
Pixmap pixmap;
char *bm_bits;
int bm_width;
int bm_height;
int mask;
} ICONS;
#endif
#ifdef HAVE_XPM
ICONS icon_list[] = {
{ 0, floppydrive_xpm,
floppydrive_bits, floppydrive_width, floppydrive_height, False},
{ 0, diskdrive_xpm,
diskdrive_bits, diskdrive_width, diskdrive_height, False},
{ 0, netdrive_xpm,
netdrive_bits, netdrive_width, netdrive_height, False},
{ 0, user_xpm,
user_bits, user_width, user_height, False},
{ 0, bell_xpm,
bell_bits, bell_width, bell_height, True},
{ 0, nobell_xpm,
nobell_bits, nobell_width, nobell_height, True},
{ 0, mouse_help_xpm,
mouse_help_bits, mouse_help_width, mouse_help_height, True},
NULL
};
ICONS mfsm_icons[] = {
{ 0, about_mfsm_xpm,
about_mfsm_bits, about_mfsm_width, about_mfsm_height, False},
{ 0, icon_xpm,
icon_bits, icon_width, icon_height, False},
NULL
};
#else
ICONS icon_list[] = {
{ 0, floppydrive_bits, floppydrive_width, floppydrive_height, False},
{ 0, diskdrive_bits, diskdrive_width, diskdrive_height, False},
{ 0, netdrive_bits, netdrive_width, netdrive_height, False},
{ 0, user_bits, user_width, user_height, False},
{ 0, bell_bits, bell_width, bell_height, True},
{ 0, nobell_bits, nobell_width, nobell_height, True},
{ 0, mouse_help_bits, mouse_help_width, mouse_help_height, True},
NULL
};
ICONS mfsm_icons[] = {
{ 0, about_mfsm_bits, about_mfsm_width, about_mfsm_height},
{ 0, icon_bits, icon_width, icon_height},
NULL
};
#endif
typedef struct drivebar_data {
char *name;
char *dev;
char *path;
int type;
int userid;
Widget widget;
Widget usagebar;
GC gc;
Pixmap pixmap;
Dimension width;
Dimension height;
float mbytes;
int usage;
int usage_type;
Widget bell_toggle;
int bell;
int bell_activated;
struct drivebar_data *next;
} DRIVE_BAR;
/**
DRIVE_BAR drivebar_test[] = {
{ "/tmp2", FLOPPY_DISK, NULL, NULL, 0, NULL, 0, 0, 0.7, 50},
{ "/home", HARD_DISK, NULL, NULL, 0, NULL, 0, 0, 52.6, 25},
{ "/tmp", NETWORK_DISK, NULL, NULL, 0, NULL, 0, 0, 16.2, 86},
{ "/home/hills", USER, NULL, NULL, 0, NULL, 0, 0, 156.2, 32},
NULL
};
**/
enum { GREEN_ALERT,
YELLOW_ALERT,
RED_ALERT
};
typedef struct _menu_item {
char *label; /* the label for the item */
WidgetClass *class; /* pushbutton, label, separator... */
Widget *widget; /* pointer to widget */
char mnemonic; /* mnemonic; '\0' if none */
char *accelerator; /* accelerator; NULL if none */
char *accel_text; /* to be converted to compound string */
char enabled; /* If menu item is enabled */
void (*callback)(); /* routine to call; NULL if none */
XtPointer callback_data; /* client_data for callback() */
struct _menu_item *subitems; /* pullright menu items, if not NULL */
} MenuItem;
String fallbacks[] = {
"Mfsm*background: grey50",
"Mfsm*fontList: -adobe-helvetica-bold-r-normal-*-*-100-*-*-*-*-*-*",
/** "Mfsm*foreground: black", **/
"Mfsm*drive.marginHeight: 5",
"Mfsm*drive.marginWidth: 5",
"Mfsm*usageBar.background: grey50",
"Mfsm*usageBar.borderWidth: 0",
"Mfsm*text.fontList: -adobe-helvetica-medium-r-normal-*-*-100-*-*-*-*-*-*",
"Mfsm*text.foreground: white",
"Mfsm*text.marginHeight: 0",
"Mfsm*text.marginWidth: 5",
"Mfsm*frame.shadowThickness: 2",
"Mfsm*_popup*background: deepskyblue4",
"Mfsm*_popup*foreground: white",
"Mfsm*About Mfsm*background: lightpink4",
"Mfsm*About Mfsm*foreground: yellow",
"Mfsm*about_text*highlightThickness: 0",
NULL
};
/* Resrcs is an object that contains "global variables" that we want the
* user to be able to initialize through resources or command line options.
* XtAppInitialize() initializes the fields in this data structure to values
* indicated by the XrmOptionsDescRec structure defined later.
*/
struct _resrcs {
XFontStruct *font; /** font to use for bitmap labels **/
float interval; /** update interval in seconds **/
float bell_interval; /** update interval in seconds **/
int width; /** width of usagebar **/
Pixel ga_color; /** green alert color **/
Pixel ya_color; /** yellow alert color **/
Pixel ra_color; /** red alert color **/
Pixel pa_color; /** panic alert color **/
int yellow_alert; /** yellow alert limit **/
int red_alert; /** red alert limit **/
int panic_alert; /** panic alert limit **/
int show_all; /** flag: select all drives **/
int show_titlebar; /** flag: title bar display **/
int show_diskused; /** flag: show disk used, not free **/
int verbose; /** flag: verbose comments **/
char *filesystem; /** list of file systems to monitor **/
} Resrcs;
/* .Xdefaults or app-defaults resources. The values listed here (the last
* field in each structure) are used as the default values for the fields
* in the Resrcs struct above.
*/
static XtResource resources[] = {
{ XmNfont, XmCFont, XmRFontStruct, sizeof(XFontStruct *),
XtOffsetOf( struct _resrcs, font), XmRString, "8x13" },
{ "interval", "Interval", XmRFloat, sizeof( float),
XtOffsetOf( struct _resrcs, interval), XmRString, "1.0"},
{ "bellInterval", "BellInterval", XmRFloat, sizeof( float),
XtOffsetOf( struct _resrcs, bell_interval), XmRString, "1.0"},
{ "greenAlertColor", "GreenAlertColor", XmRPixel, sizeof( Pixel),
XtOffsetOf( struct _resrcs, ga_color), XmRString, "green"},
{ "yellowAlertColor", "YellowAlertColor", XmRPixel, sizeof ( Pixel),
XtOffsetOf( struct _resrcs, ya_color), XmRString, "yellow"},
{ "redAlertColor", "RedAlertColor", XmRPixel, sizeof( Pixel),
XtOffsetOf( struct _resrcs, ra_color), XmRString, "red"},
{ "panicAlertColor", "PanicAlertColor", XmRPixel, sizeof( Pixel),
XtOffsetOf( struct _resrcs, pa_color), XmRString, "gold3"},
{ "panicAlertLimit", "PanicAlertLimit", XmRInt, sizeof( int),
XtOffsetOf( struct _resrcs, panic_alert), XmRImmediate, (char *)99},
{ "redAlertLimit", "redAlertLimit", XmRInt, sizeof( int),
XtOffsetOf( struct _resrcs, red_alert), XmRImmediate, (char *)95},
{ "yellowAlertLimit", "YellowAlertLimit", XmRInt, sizeof( int),
XtOffsetOf( struct _resrcs, yellow_alert), XmRImmediate, (char *)75},
{ "showAllDrives", "ShowAllDrives", XmRBoolean, sizeof( int),
XtOffsetOf( struct _resrcs, show_all), XmRImmediate, False},
{ "fileSystem", "FileSystem", XmRString, sizeof(char *),
XtOffsetOf( struct _resrcs, filesystem), XmRString, "" },
{ "verbose", "Verbose", XmRBoolean, sizeof( int),
XtOffsetOf( struct _resrcs, verbose), XmRImmediate, (char *)False},
{ "usageBarWidth", "UsageBarWidth", XmRInt, sizeof( int),
XtOffsetOf( struct _resrcs, width), XmRImmediate, (char *)400},
{ "showTitleBar", "ShowTitleBar", XmRBoolean, sizeof( int),
XtOffsetOf( struct _resrcs, show_titlebar), XmRImmediate,(char *)True},
{ "showDiskUsed", "ShowDiskUsed", XmRBoolean, sizeof( int),
XtOffsetOf( struct _resrcs, show_diskused), XmRImmediate,(char *)False},
};
/* If the following command line args (1st field) are found, set the
* associated resource values (2rnd field) to the given value (4th field).
*/
static XrmOptionDescRec options[] = {
{ "-a", "showAllDrives", XrmoptionNoArg, "True" },
{ "-fs", "fileSystem", XrmoptionSepArg, NULL },
{ "-fn", "font", XrmoptionSepArg, NULL },
{ "-int", "interval", XrmoptionSepArg, NULL },
{ "-bellint", "bellInterval", XrmoptionSepArg, NULL },
{ "-gacol", "redAlert.Color", XrmoptionSepArg, NULL },
{ "-racol", "redAlert.Color", XrmoptionSepArg, NULL },
{ "-yacol", "yellowAlertColor", XrmoptionSepArg, NULL },
{ "-paniclim", "panicAlertLimit", XrmoptionSepArg, NULL },
{ "-ralim", "redAlertLimit", XrmoptionSepArg, NULL },
{ "-yalim", "yellowAlertLimit", XrmoptionSepArg, NULL },
{ "-u", "showDiskUsed", XrmoptionNoArg, "True" },
{ "-v", "verbose", XrmoptionNoArg, "True" },
{ "-width", "usageBarWidth", XrmoptionSepArg, NULL },
{ "-t", "showTitleBar", XrmoptionNoArg, "False" },
};
#define VERSION "Mfsm V-1.1 by SDH EngSoft (c) 1995"
#define MAX_LINE 128
#if defined(SGI) || defined(SOLARIS)
# define DF_COMMAND "/bin/df -k"
#else
# define DF_COMMAND "/bin/df"
#endif
String about_text[] = {
VERSION,
"All Rights Reserved\n\n",
"Motif File System Monitor and Alert System\n\n",
"Arguments to Mfsm:\n\n",
"-a\t\tshow all mounted file systems.\n",
"-fs file:file:...\tmonitor given file system.\n",
"-int sec\t\tusage bar update interval in seconds.\n",
"-bellint sec\talert bell interval in seconds.\n",
"-gacol colour\tgreen alert colour.\n",
"-yacol colour\tyellow alert colour.\n",
"-racol colour\tred alert colour.\n",
"-pacol colour\tpanic alert colour.\n",
"-yalim percent\tyellow alert limit percent.\n",
"-ralim percent\tred alert limit percent.\n",
"-palim percent\tpanic alert limit percent.\n",
"-t\t\tremove title bar.\n",
"-u\t\tshow disk space used, not free.\n",
"-v\t\tverbose mode.\n",
"-width val\t\twidth in pixels of usage bar.\n\n",
"Keyboard Commands:\n\n",
"a\tabout Mfsm.\n",
"f\tdisplay filesystem freespace (default).\n",
"q\tquit Mfsm.\n",
"u\tdisplay filesystem usage.\n",
"v\ttoggle verbose information.\n",
NULL
};
XtAppContext app;
Widget toplevel = NULL;
Widget popup_menu = NULL;
XtTranslations transTable;
char *progname = NULL;
DRIVE_BAR *drivebar = NULL;
char hostname[ MAX_LINE];
Widget BuildMenu( Widget parent, int menu_type, char *menu_title,
char menu_mnemonic, MenuItem *items);
void quit_mfsm( Widget w, XButtonEvent *event, String *args,
int *nargs);
void activate_popup( Widget w, XtPointer client_data,
XButtonPressedEvent *event);
void about( Widget w, XButtonEvent *event, String *args,
int *nargs);
void DestroyShell( Widget widget, Widget *dialog);
void set_display( Widget w, XButtonEvent *event, String *args,
int *nargs);
void init_pixmaps( Widget w);
int load_icon( Widget w, ICONS *icon);
void init_colors( Widget w);
void create_drivebar( Widget w, DRIVE_BAR *dbar);
void fs_monitor( XtPointer client_data, XtIntervalId *id);
void alert_bell( XtPointer *client_data, XtIntervalId *id);
void init_usage_bar( DRIVE_BAR *dbar);
void draw_usage_bar( DRIVE_BAR *dbar);
void expose_redraw( Widget w, XtPointer client_data,
XmDrawnButtonCallbackStruct *cbs);
void toggle_bell( Widget w, int item,
XmToggleButtonCallbackStruct *state);
unsigned long get_alert_color( int usage);
DRIVE_BAR *get_defined_drives( DRIVE_BAR *dbar);
DRIVE_BAR *get_all_drives( DRIVE_BAR *dbar);
DRIVE_BAR *add_drivebar( DRIVE_BAR *dbar, char *dev, char *path);
void get_drive_type( DRIVE_BAR *dbar);
char *readlink_path( char *path);
void getfsinfo( DRIVE_BAR *dbar);
#ifdef USE_IOCTL
int quotactl(int cmd, char *special, uid_t uid, struct dqblk * addr);
#endif
void check_args( int nargs, char **argv);
void fatal( char *fmt, ...);
void warning( char *fmt, ...);
int fget_line( char *s, int lim, FILE *fp);
int searchfor( char *string, char *test);
Widget tmp_widget;
MenuItem popup_items[] = {
{ "Mfsm Menu", &xmLabelWidgetClass, &tmp_widget,
'\0', NULL, NULL, True,
NULL, NULL, NULL},
{ "Separator", &xmSeparatorWidgetClass, &tmp_widget,
'\0', NULL, NULL, True,
NULL, NULL, NULL},
{ "About", &xmPushButtonWidgetClass, &tmp_widget,
'A', "Ctrl<Key>A", "Ctrl A", True,
about, NULL, NULL},
{ "Quit", &xmPushButtonWidgetClass, &tmp_widget,
'Q', "Ctrl<Key>C", "Ctrl C", True,
quit_mfsm, NULL, NULL},
NULL
};
XtActionsRec actionsTable[] = {
{ "about", (XtActionProc) about},
{ "set_display", (XtActionProc) set_display},
{ "quit", (XtActionProc) quit_mfsm}
};
char defaultTranslations[] =
"<Key>a: about()\n\
<Key>f: set_display(freespace)\n\
<Key>q: quit()\n\
<Key>u: set_display(usage)\n\
<Key>v: set_display(verbose)";
void main( int nargs, char *argv[])
{
Widget form;
Widget rowcolumn;
Widget label1, label2, label3;
DRIVE_BAR *dbar;
XmString string;
char *h;
long int decor;
Window iconWindow;
unsigned int iconW = 40, iconH = 40, tmp;
progname = *argv;
Resrcs.show_titlebar = True;
check_args( nargs, argv);
decor = (Resrcs.show_titlebar) ? MWM_DECOR_ALL :
MWM_DECOR_BORDER | MWM_DECOR_RESIZEH;
toplevel = XtVaAppInitialize(
&app, "Mfsm",
options, XtNumber( options), &nargs, argv, fallbacks,
XmNmwmDecorations, decor,
NULL);
XtAppAddActions( app, actionsTable, XtNumber(actionsTable));
transTable = XtParseTranslationTable( defaultTranslations);
XtGetApplicationResources(
toplevel, &Resrcs,
resources, XtNumber(resources), NULL, 0);
form = XtVaCreateManagedWidget(
"form",
xmFormWidgetClass, toplevel,
NULL);
XtOverrideTranslations( form, transTable);
init_pixmaps( form);
/**
Create icon for program.
**/
#ifdef HAVE_XPM
iconWindow = XCreateSimpleWindow(
XtDisplay( toplevel), RootWindowOfScreen( XtScreen( toplevel)),
0, 0, /* x, y */
icon_width, icon_height, 0,
BlackPixelOfScreen( XtScreen( toplevel)),
BlackPixelOfScreen( XtScreen( toplevel)));
XSetWindowBackgroundPixmap( XtDisplay( toplevel), iconWindow,
mfsm_icons[ ICONIC].pixmap);
XtVaSetValues( toplevel, XtNiconWindow, iconWindow, NULL);
#else
XtVaSetValues ( toplevel,
XmNiconPixmap, mfsm_icons[ ICONIC].pixmap,
NULL);
#endif
/** init_colors( form); **/
rowcolumn = XtVaCreateManagedWidget(
"drive",
xmRowColumnWidgetClass, form,
XmNpacking, XmPACK_TIGHT,
XmNorientation, XmVERTICAL,
XmNtopAttachment, XmATTACH_FORM,
XmNleftAttachment, XmATTACH_FORM,
NULL);
popup_menu = BuildMenu( rowcolumn, XmMENU_POPUP, NULL, '\0',
popup_items);
XtAddEventHandler( rowcolumn, ButtonPressMask, False,
(XtEventHandler) activate_popup, NULL);
if ( Resrcs.show_all) {
drivebar = get_all_drives( drivebar);
}
drivebar = get_defined_drives( drivebar);
if ( drivebar == NULL)
fatal( "No filesystems given to monitor.\nTry the commands:\n\tmfsm -a\n\tmfsm -fs $HOME:/tmp\n");
dbar = drivebar;
while ( dbar != NULL) {
create_drivebar( rowcolumn, dbar);
dbar = dbar->next;
}
h = hostname;
strcpy( h, "Host: ");
h = h + strlen( hostname);
if ( gethostname( h, MAX_LINE) != 0)
strcpy( h, "Not defined");
string = XmStringCreateSimple( hostname);
label1 = XtVaCreateManagedWidget(
"text",
xmLabelWidgetClass, form,
XmNlabelString, string,
XmNalignment, XmALIGNMENT_BEGINNING,
XmNtopAttachment, XmATTACH_WIDGET,
XmNtopWidget, rowcolumn,
NULL);
XmStringFree( string);
XtAddEventHandler( label1, ButtonPressMask, False,
(XtEventHandler) activate_popup, NULL);
string = XmStringCreateSimple( VERSION);
label2 = XtVaCreateManagedWidget(
"text",
xmLabelWidgetClass, form,
XmNlabelString, string,
XmNalignment, XmALIGNMENT_END,
XmNtopAttachment, XmATTACH_WIDGET,
XmNtopWidget, rowcolumn,
XmNrightAttachment, XmATTACH_FORM,
NULL);
XmStringFree( string);
XtAddEventHandler( label2, ButtonPressMask, False,
(XtEventHandler) activate_popup, NULL);
label3 = XtVaCreateManagedWidget(
"text",
xmLabelWidgetClass, form,
XmNlabelType, XmPIXMAP,
XmNlabelPixmap, icon_list[ MOUSE_HELP].pixmap,
XmNalignment, XmALIGNMENT_CENTER,
XmNtopAttachment, XmATTACH_WIDGET,
XmNtopWidget, rowcolumn,
XmNleftAttachment, XmATTACH_WIDGET,
XmNleftWidget, label1,
XmNrightAttachment, XmATTACH_WIDGET,
XmNrightWidget, label2,
NULL);
XtAddEventHandler( label3, ButtonPressMask, False,
(XtEventHandler) activate_popup, NULL);
XtAppAddTimeOut( app, (unsigned long int) ( Resrcs.interval * 1000.0),
fs_monitor, (XtPointer) app);
if ( Resrcs.verbose)
warning( "Going to XWindows loop ...");
XtRealizeWidget(toplevel);
XtAppMainLoop(app);
}
Widget BuildMenu( Widget parent, int menu_type, char *menu_title,
char menu_mnemonic, MenuItem *items)
{
Widget menu, cascade = NULL, widget;
XmString str;
int i;
if ( menu_type == XmMENU_PULLDOWN) {
menu = XmCreatePulldownMenu( parent, "_pulldown", NULL, 0);
str = XmStringCreateSimple( menu_title);
cascade = XtVaCreateManagedWidget(
menu_title,
xmCascadeButtonWidgetClass, parent,
XmNsubMenuId, menu,
XmNlabelString, str,
XmNmnemonic, menu_mnemonic,
NULL);
XmStringFree(str);
} else
menu = XmCreatePopupMenu( parent, "_popup", NULL, 0);
/* Now add the menu items */
for (i = 0; items[i].label != NULL; i++) {
/* If subitems exist, create the pull-right menu by calling this
* function recursively. Since the function returns a cascade
* button, the widget returned is used..
*/
if (items[i].subitems)
widget = BuildMenu(
menu, XmMENU_PULLDOWN,
items[i].label, items[i].mnemonic, items[i].subitems);
else
widget = XtVaCreateManagedWidget(
items[i].label, *items[i].class, menu,
NULL);
*(items[i].widget) = widget;
/* Whether the item is a real item or a cascade button with a
* menu, it can still have a mnemonic.
*/
if (items[i].mnemonic)
XtVaSetValues(widget, XmNmnemonic, items[i].mnemonic, NULL);
/* any item can have an accelerator, except cascade menus. But,
* we don't worry about that; we know better in our declarations.
*/
if (items[i].accelerator) {
str = XmStringCreateSimple(items[i].accel_text);
XtVaSetValues(widget,
XmNaccelerator, items[i].accelerator,
XmNacceleratorText, str,
NULL);
XmStringFree(str);
}
/* again, anyone can have a callback -- however, this is an
* activate-callback. This may not be appropriate for all items.
*/
if (items[i].callback)
XtAddCallback(widget, XmNactivateCallback,
items[i].callback, items[i].callback_data);
XtSetSensitive( widget, items[i].enabled);
}
return( menu_type == XmMENU_POPUP ? menu : cascade);
}
void quit_mfsm( Widget w, XButtonEvent *event, String *args, int *nargs)
{
exit( 0);
}
void activate_popup( Widget w, XtPointer client_data,
XButtonPressedEvent *event)
{
if ( event->button == 3) {
if ( popup_menu == NULL)
popup_menu = BuildMenu( w, XmMENU_POPUP, NULL, '\0',
popup_items);
XmMenuPosition( popup_menu, event);
XtManageChild( popup_menu);
}
}
void about( Widget w, XButtonEvent *event, String *args, int *nargs)
{
static Widget about_dialog = NULL;
Widget pane, text_w, form, button, label;
Position width, height;
Arg arg_list[9];
int i;
char *p, buf[ BUFSIZ];
if ( about_dialog == NULL) {
about_dialog = XtVaCreatePopupShell(
"About Mfsm",
xmDialogShellWidgetClass, toplevel,
XmNdeleteResponse, XmDESTROY,
XmNmwmDecorations,
MWM_DECOR_BORDER | MWM_DECOR_TITLE | MWM_DECOR_RESIZEH,
XmNminWidth, 400,
XmNminHeight, 300,
NULL);
pane = XtVaCreateWidget(
"pane", xmPanedWindowWidgetClass, about_dialog,
XmNsashWidth, 1, /* PanedWindow won't let us set these to 0! */
XmNsashHeight, 1, /* Make small so user doesn't try to resize */
NULL);
form = XtVaCreateWidget(
"form1",
xmFormWidgetClass, pane,
NULL);
if ( mfsm_icons[ ABOUT].pixmap == 0)
load_icon( form, &mfsm_icons[ ABOUT]);
label = XtVaCreateManagedWidget(
"pixmap", xmLabelWidgetClass, form,
XmNlabelType, XmPIXMAP,
XmNlabelPixmap, mfsm_icons[ ABOUT].pixmap,
XmNtopAttachment, XmATTACH_FORM,
XmNleftAttachment, XmATTACH_FORM,
XmNrightAttachment, XmATTACH_FORM,
NULL);
for ( p = buf, i = 0; about_text[i]; i++) {
p += strlen( strcpy( p, about_text[i]));
if (!isspace(p[-1])) /* spaces tabs and newlines are spaces.. */
*p++ = ' '; /* lines are concatenated together, insert a space */
}
*--p = 0; /* get rid of trailing space... */
XtSetArg(arg_list[0], XmNscrollVertical, True);
XtSetArg(arg_list[1], XmNscrollHorizontal, False);
XtSetArg(arg_list[2], XmNeditMode, XmMULTI_LINE_EDIT);
XtSetArg(arg_list[3], XmNeditable, False);
XtSetArg(arg_list[4], XmNcursorPositionVisible, False);
XtSetArg(arg_list[5], XmNwordWrap, False);
XtSetArg(arg_list[6], XmNvalue, buf);
XtSetArg(arg_list[7], XmNrows, 5);
text_w = XmCreateScrolledText(form, "about_text", arg_list, 8);
XtVaSetValues( XtParent(text_w),
XmNtopAttachment, XmATTACH_WIDGET,
XmNtopWidget, label,
XmNleftAttachment, XmATTACH_FORM,
XmNrightAttachment, XmATTACH_FORM,
XmNbottomAttachment, XmATTACH_FORM,
NULL);
XtManageChild( text_w);
XtManageChild( form);
form = XtVaCreateWidget(
"form", xmFormWidgetClass, pane,
XmNfractionBase, 5,
NULL);
button = XtVaCreateManagedWidget(
"Ok",
xmPushButtonWidgetClass, form,
XmNtopAttachment, XmATTACH_FORM,
XmNbottomAttachment, XmATTACH_FORM,
XmNleftAttachment, XmATTACH_POSITION,
XmNleftPosition, 2,
XmNrightAttachment, XmATTACH_POSITION,
XmNrightPosition, 3,
XmNshowAsDefault, True,
XmNdefaultButtonShadowThickness, 1,
NULL);
XtAddCallback( button, XmNactivateCallback,
(XtCallbackProc) DestroyShell, &about_dialog);
XtManageChild( form);
{
Dimension h;
XtVaGetValues( button, XmNheight, &h, NULL);
XtVaSetValues(form, XmNpaneMaximum, h, XmNpaneMinimum, h, NULL);
}
XtManageChild( pane);
/**
Position about window in middle upper third of screen.
**/
XtVaGetValues( about_dialog,
XmNheight, &height,
XmNwidth, &width,
NULL);
XtVaSetValues(
about_dialog,
XmNx, ( WidthOfScreen( XtScreen( toplevel)) - width) / 2,
XmNy, ( HeightOfScreen( XtScreen( toplevel)) - height) / 3,
NULL);
XtPopup( about_dialog, XtGrabNone);
}
}
void DestroyShell( Widget w, Widget *dialog)
{
XtDestroyWidget( *dialog);
if ( mfsm_icons[ ABOUT].pixmap != 0) {
XFreePixmap( XtDisplay( *dialog), mfsm_icons[ ABOUT].pixmap);
mfsm_icons[ ABOUT].pixmap = 0;
}
*dialog = (Widget) NULL;
}
void set_display( Widget w, XButtonEvent *event, String *args, int *nargs)
{
int nitems = *nargs;
if ( Resrcs.verbose)
warning( "set_display: NArgs = %d Arg = \"%s\"\n", nitems, *args);
while ( nitems) {
if ( strcmp( *args, "freespace") == 0)
Resrcs.show_diskused = False;
else if ( strcmp( *args, "usage") == 0)
Resrcs.show_diskused = True;
else if ( strcmp( *args, "verbose") == 0)
Resrcs.verbose = !Resrcs.verbose;
if ( --nitems != 0)
++args;
}
}
void init_pixmaps( Widget w)
{
ICONS *icon;
icon = icon_list;
while( icon->bm_bits != NULL) {
load_icon( w, icon);
++icon;
}
load_icon( w, &mfsm_icons[ ICONIC]);
}
int load_icon( Widget w, ICONS *icon)
{
Pixel fg, bg;
Screen *scr;
#ifdef HAVE_XPM
XpmAttributes pixmapAttrs;
Pixmap pixmapShapeMask = (Pixmap) NULL;
XpmColorSymbol pixmapColorSymbols[ 1];
int xpm_error;
#endif
scr = XtScreen( w);
XtVaGetValues( w,
XmNforeground, &fg,
XmNbackground, &bg,
NULL);
if ( Resrcs.verbose)
warning( "pixmap fg = %d bg = %d\n", fg, bg);
#ifdef HAVE_XPM
pixmapColorSymbols[0].name = NULL;
pixmapColorSymbols[0].value = "none";
pixmapColorSymbols[0].pixel = bg;
pixmapColorSymbols[0].name = NULL;
pixmapAttrs.colorsymbols = pixmapColorSymbols;
pixmapAttrs.numsymbols = 1;
pixmapAttrs.closeness = 20000;
pixmapAttrs.valuemask =
XpmColorSymbols | XpmCloseness;
if ( icon->xpm_data == NULL || ( xpm_error = XpmCreatePixmapFromData(
XtDisplay( w),
RootWindowOfScreen( scr),
icon->xpm_data, &icon->pixmap, &pixmapShapeMask,
&pixmapAttrs)) != XpmSuccess) {
if ( !icon->mask) {
fg = BlackPixelOfScreen( scr);
bg = WhitePixelOfScreen( scr);
}
icon->pixmap = XCreatePixmapFromBitmapData(
XtDisplay( w),
RootWindowOfScreen( scr),
icon->bm_bits, icon->bm_width, icon->bm_height,
1, 0, /**fg, bg,**/
DefaultDepthOfScreen( scr));
if ( Resrcs.verbose)
warning( "XPM error - %d", xpm_error);
} else
if ( icon->xpm_data != NULL && pixmapShapeMask != 0)
XFreePixmap( XtDisplay( w), pixmapShapeMask);
#else
if ( !icon->mask) {
fg = BlackPixelOfScreen( scr);
bg = WhitePixelOfScreen( scr);
}
icon->pixmap = XCreatePixmapFromBitmapData(
XtDisplay( w),
RootWindowOfScreen( scr),
icon->bm_bits, icon->bm_width, icon->bm_height,
fg, bg,
DefaultDepthOfScreen( scr));
#endif
return( icon->pixmap != 0 ? True : False);
}
/**
void init_colors( Widget w)
{
Display *dpy = XtDisplay( w);
Colormap cmap = DefaultColormapOfScreen( XtScreen( w));
XColor unused;
int i;
for ( i = 0; i < MAX_ALERT_COLORS; ++i) {
if ( !XAllocNamedColor( dpy, cmap, bar_color[ i], &alert_color[ i], &unused)) {
char buf[ 32];
sprintf( "Can't allocate color %s", bar_color[ i]);
XtWarning( buf);
exit( 1);
}
}
}
**/
void create_drivebar( Widget w, DRIVE_BAR *dbar)
{
Widget rowcolumn1, frame1;
Widget label1;
Widget drawing1;
Widget toggle1;
rowcolumn1 = XtVaCreateManagedWidget(
"rowcolumn",
xmRowColumnWidgetClass, w,
XmNpacking, XmPACK_TIGHT,
XmNorientation, XmHORIZONTAL,
XmNmarginHeight, 0,
XmNmarginWidth, 0,
XmNleftAttachment, XmATTACH_FORM,
XmNrightAttachment, XmATTACH_FORM,
NULL);
label1 = XtVaCreateManagedWidget(
"pixmap",
xmLabelWidgetClass, rowcolumn1,
XmNlabelType, XmPIXMAP,
XmNlabelPixmap, icon_list[ dbar->type].pixmap,
NULL);
XtOverrideTranslations( label1, transTable);
frame1 = XtVaCreateManagedWidget(
"frame",
xmFrameWidgetClass, rowcolumn1,
XmNshadowType, XmSHADOW_IN,
XmNmarginWidth, 0,
XmNmarginHeight, 0,
NULL);
drawing1 = XtVaCreateManagedWidget(
"usageBar",
xmDrawingAreaWidgetClass, frame1,
/** XmNresizePolicy, XmRESIZE_NONE, **/
XmNwidth, Resrcs.width,
NULL);
XtOverrideTranslations( drawing1, transTable);
XtAddCallback( drawing1, XmNexposeCallback,
(XtCallbackProc) expose_redraw, NULL);
toggle1 = XtVaCreateManagedWidget(
"toggle",
xmToggleButtonWidgetClass, rowcolumn1,
XmNlabelType, XmPIXMAP,
XmNlabelPixmap, icon_list[ NOBELL].pixmap,
XmNselectPixmap, icon_list[ BELL].pixmap,
XmNhighlightThickness, 0,
NULL);
XmToggleButtonSetState( toggle1, dbar->bell, False);
XtOverrideTranslations( toggle1, transTable);
XtAddCallback( toggle1, XmNvalueChangedCallback,
(XtCallbackProc) toggle_bell, NULL);
dbar->widget = rowcolumn1;
dbar->usagebar = drawing1;
dbar->gc = XCreateGC( XtDisplay( drawing1),
RootWindowOfScreen( XtScreen( drawing1)),
0, NULL);
dbar->bell_toggle = toggle1;
}
void fs_monitor( XtPointer client_data, XtIntervalId *id)
{
DRIVE_BAR *dbar;
if ( Resrcs.verbose)
warning( "fs_monitor ...");
dbar = drivebar;
while ( dbar != NULL) {
if ( dbar->pixmap != 0)
getfsinfo( dbar);
draw_usage_bar( dbar);
dbar = dbar->next;
}
XtAppAddTimeOut( (XtAppContext) client_data,
(unsigned long int) ( Resrcs.interval * 1000.0),
fs_monitor, client_data);
}
void alert_bell( XtPointer *client_data, XtIntervalId *id)
{
DRIVE_BAR *dbar = (DRIVE_BAR *) client_data;
if ( dbar->bell && dbar->bell_activated) {
XBell( XtDisplay( dbar->widget), 50);
XtAppAddTimeOut( app,
(unsigned long int)( Resrcs.bell_interval * 1000.0),
(XtTimerCallbackProc) alert_bell, (XtPointer) dbar);
} else {
XtRemoveTimeOut( *id);
dbar->bell_activated = False;
}
}
void init_usage_bar( DRIVE_BAR *dbar)
{
Display *dpy;
Screen *scr;
Pixel bg;
int i, x;
dpy = XtDisplay( dbar->usagebar);
scr = XtScreen( dbar->usagebar);
XtVaGetValues( dbar->usagebar,
XmNwidth, &(dbar->width),
XmNheight, &(dbar->height),
XmNbackground, &bg,
NULL);
if ( dbar->pixmap == 0 && dbar->width != 0 && dbar->height != 0) {
dbar->pixmap = XCreatePixmap(
dpy,
RootWindowOfScreen( scr),
dbar->width, dbar->height,
DefaultDepthOfScreen( scr));
}
XSetForeground( dpy, dbar->gc, bg);
XFillRectangle( dpy, dbar->pixmap, dbar->gc,
0, 0, dbar->width, dbar->height);
/**
Draw Tic marks
**/
XSetForeground( dpy, dbar->gc, BlackPixelOfScreen( scr));
for ( i = 2; i < 10; i += 2) {
x = dbar->width * i / 10;
XFillRectangle( dpy, dbar->pixmap, dbar->gc, x, 0, 2, 3);
XFillRectangle( dpy, dbar->pixmap, dbar->gc, x, dbar->height - 3,
2, 3);
}
XSetFont( dpy, dbar->gc, Resrcs.font->fid);
}
void draw_usage_bar( DRIVE_BAR *dbar)
{
Display *dpy;
Window win;
Screen *scr;
Pixel bg;
char buf[ 16];
int x, y, font_dim;
int bar_x1, bar_y1, bar_x2, bar_y2;
int text_margin = 3;
XPoint points[ 4];
dpy = XtDisplay( dbar->usagebar);
win = XtWindow( dbar->usagebar);
scr = XtScreen( dbar->usagebar);
bar_x1 = 0;
bar_y1 = 3;
bar_x2 = dbar->width * dbar->usage / 100;
bar_y2 = dbar->height - 6;
/**
Secondary test to make sure tha a pixmap has been allocated.
**/
if ( dbar->pixmap == 0)
return;
/**
Draw usage bar
**/
XtVaGetValues( dbar->usagebar, XmNbackground, &bg, NULL);
XSetForeground( dpy, dbar->gc, bg);
XFillRectangle( dpy, dbar->pixmap, dbar->gc,
bar_x1, bar_y1, dbar->width, bar_y2);
if ( dbar->usage < Resrcs.panic_alert) {
XSetForeground( dpy, dbar->gc, get_alert_color( dbar->usage));
XFillRectangle( dpy, dbar->pixmap, dbar->gc,
bar_x1, bar_y1, bar_x2, bar_y2);
dbar->bell_activated = False;
} else {
XSetForeground( dpy, dbar->gc, BlackPixelOfScreen( scr));
XFillRectangle( dpy, dbar->pixmap, dbar->gc,
bar_x1, bar_y1, bar_x2, bar_y2);
XSetForeground( dpy, dbar->gc, Resrcs.pa_color);
for ( x = dbar->height; x <= bar_x2; x += 2 * dbar->height) {
points[ 0].x = x;
points[ 0].y = bar_y1;
points[ 1].x = x + dbar->height;
points[ 1].y = bar_y1;
points[ 2].x = x;
points[ 2].y = bar_y2 + 3;
points[ 3].x = x - dbar->height;
points[ 3].y = bar_y2 + 3;
XFillPolygon( dpy, dbar->pixmap, dbar->gc, points, 4,
Convex, CoordModeOrigin);
}
if ( dbar->bell && !dbar->bell_activated) {
dbar->bell_activated = True;
XBell( dpy, 50);
XtAppAddTimeOut(
app, (unsigned long int)( Resrcs.bell_interval * 1000.0),
(XtTimerCallbackProc) alert_bell, (XtPointer) dbar);
}
}
XSetForeground( dpy, dbar->gc, WhitePixelOfScreen( scr));
XDrawLine( dpy, dbar->pixmap, dbar->gc, bar_x1, bar_y1, bar_x2, bar_y1);
XSetForeground( dpy, dbar->gc, BlackPixelOfScreen( scr));
XDrawLine( dpy, dbar->pixmap, dbar->gc,
bar_x1, bar_y2 + 2, bar_x2, bar_y2 + 2);
XDrawLine( dpy, dbar->pixmap, dbar->gc,
bar_x2, bar_y1, bar_x2, bar_y2 + 2);
/**
Draw Text
**/
/** font_info = XQueryFont( dpy, XGContextFromGC( dbar->gc)); **/
font_dim = Resrcs.font->ascent + Resrcs.font->descent;
y = ( dbar->height - font_dim) / 2 + Resrcs.font->ascent;
XDrawString( dpy, dbar->pixmap, dbar->gc, text_margin, y,
dbar->name, strlen( dbar->name));
if ( dbar->usage_type == QUOTA_SPACE)
sprintf( buf, "%3.2fMb (Q)", dbar->mbytes);
else
sprintf( buf, "%3.2fMb", dbar->mbytes);
font_dim = XTextWidth( Resrcs.font, buf, strlen( buf));
XDrawString( dpy, dbar->pixmap, dbar->gc,
dbar->width - font_dim - text_margin, y,
buf, strlen( buf));
/**
Swap pixmap to screen.
**/
XCopyArea( dpy, dbar->pixmap, win, dbar->gc, 0, 0,
dbar->width, dbar->height, 0, 0);
}
void expose_redraw( Widget w, XtPointer client_data,
XmDrawnButtonCallbackStruct *cbs)
{
DRIVE_BAR *dbar;
Pixel bg;
dbar = drivebar;
while ( dbar != NULL && dbar->usagebar != w)
dbar = dbar->next;
if ( dbar == NULL) {
warning( "expose_redraw: Widget not found\n");
return;
}
if (cbs->reason == XmCR_EXPOSE) {
init_usage_bar( dbar);
draw_usage_bar( dbar);
} else { /* XmCR_RESIZE */
XtVaGetValues( dbar->usagebar,
XmNwidth, &(dbar->width),
XmNheight, &(dbar->height),
XmNbackground, &bg,
NULL);
puts("Usage Bar Resize");
}
}
void toggle_bell( Widget w, int item,
XmToggleButtonCallbackStruct *state)
{
DRIVE_BAR *dbar;
dbar = drivebar;
while ( dbar != NULL && dbar->bell_toggle != w)
dbar = dbar->next;
if ( dbar == NULL) {
warning( "toggle_bell: Widget not found\n");
return;
}
dbar->bell = state->set;
}
unsigned long get_alert_color( int usage)
{
if ( usage < Resrcs.yellow_alert )
return( Resrcs.ga_color);
else if ( usage < Resrcs.red_alert)
return( Resrcs.ya_color);
else
return( Resrcs.ra_color);
}
DRIVE_BAR *get_defined_drives( DRIVE_BAR *dbar)
{
char tmp[ 2 * MAX_LINE];
FILE *ifp;
char *s, *fs;
char tmp_file[] = "/tmp/mfsm-XXXXXX";
char *dev;
mktemp( tmp_file);
fs = Resrcs.filesystem;
while ( fs != NULL && strlen( fs) != 0) {
if (( s = strchr( fs, ':')) != NULL) {
*s = '\0';
++s;
}
sprintf( tmp, "%s %s >%s", DF_COMMAND, fs, tmp_file);
if ( system( tmp) != 0)
fatal( "Can't run df command for file system %s", fs);
if (( ifp = fopen( tmp_file, "r")) == NULL)
fatal( "Can't read temp file for df command");
#ifndef SCO
fget_line( tmp, MAX_LINE, ifp);
#endif
while ( fget_line( tmp, MAX_LINE, ifp) != EOF) {
/**
BSD df returns the format:
device other_info mount_point
SVR4 df returns the format:
mount_point (device) other_info
**/
/**
Search for device.
**/
#ifdef USE_SVR4DF /** SRVR4 df(1) **/
if (( dev = strchr( tmp, '(')) == NULL) {
warning( "The df(1) command is not a SVR4 version.");
fatal( "Try compiling without -DUSE_SRV4DF.");
}
strcpy( tmp, dev + 1);
#endif
dev = tmp;
while( !isspace( *dev) && *dev != ')')
++dev;
*dev = '\0';
dbar = add_drivebar( dbar, tmp, fs);
}
fclose( ifp);
unlink( tmp_file);
fs = s;
}
return( dbar);
}
DRIVE_BAR *get_all_drives( DRIVE_BAR *dbar)
{
char tmp[ 2 * MAX_LINE];
FILE *ifp;
char tmp_file[] = "/tmp/mfsm-XXXXXX";
char *path, *dev;
mktemp( tmp_file);
sprintf( tmp, "%s >%s", DF_COMMAND, tmp_file);
if ( system( tmp) != 0)
fatal( "Can't run df command");
if (( ifp = fopen( tmp_file, "r")) == NULL)
fatal( "Can't read temp file for df command");
#ifndef SCO
fget_line( tmp, MAX_LINE, ifp);
#endif
while ( fget_line( tmp, MAX_LINE, ifp) != EOF) {
/**
BSD df returns the format:
device other_info mount_point
SVR4 df returns the format:
mount_point (device) other_info
**/
/**
Search for path.
**/
#ifdef USE_SVR4DF /** SVR4 df(1) **/
path = tmp;
while( !isspace( *path) && *path != '(')
++path;
if (( dev = strchr( path, '(')) == NULL) {
warning( "The df(1) command is not a SVR4 version.");
fatal( "Try compiling without -DUSE_SRV4DF.");
}
*path = '\0';
path = tmp;
++dev;
while( !isspace( *dev) && *dev != ')')
++dev;
*dev = '\0';
#else /** BSD df(1) **/
path = tmp + strlen( tmp) - 1; /** Save the end pointer **/
/**
Check if line is split, and read another if needed
**/
if (( dev = strchr( tmp, '%')) == NULL) {
fget_line( path, MAX_LINE, ifp);
path = tmp + strlen( tmp) - 1; /** Save new end pointer **/
}
/**
Eat spaces at end of line.
**/
while( isspace( *path))
*(path--) = '\0';
/**
Then take the pathname.
**/
while( !isspace( *path))
--path;
++path;
/**
Search for device.
**/
dev = tmp;
while( !isspace( *dev))
++dev;
*dev = '\0';
dev = tmp;
#endif
#ifdef SOLARIS
if ( !strcmp( dev, "/proc") || !strcmp( dev, "fd"))
continue;
#endif
dbar = add_drivebar( dbar, dev, path);
}
fclose( ifp);
unlink( tmp_file);
return( dbar);
}
DRIVE_BAR *add_drivebar( DRIVE_BAR *dbar, char *dev, char *path)
{
if ( dbar == NULL) {
if (( dbar = (DRIVE_BAR *) malloc( sizeof( DRIVE_BAR))) == NULL)
fatal( "Can't allocate memory for drive \"%s\"\n", path);
dbar->name = strdup( path);
dbar->dev = strdup( dev);
dbar->path = readlink_path( path);
/**
Make sure that the path is not a link.
**/
if ( Resrcs.verbose)
warning( "Link for path \'%s\" is \"%s\"\n",
dbar->name, dbar->path);
dbar->userid = 0;
dbar->type = 0;
get_drive_type( dbar);
dbar->widget = NULL;
dbar->usagebar = NULL;
dbar->gc = NULL;
dbar->pixmap = 0;
dbar->width = 0;
dbar->height = 0;
dbar->mbytes = 0.0;
dbar->usage = 0;
dbar->bell_toggle = NULL;
dbar->bell = True;
dbar->bell_activated = False;
dbar->next = NULL;
} else
dbar->next = add_drivebar( dbar->next, dev, path);
return( dbar);
}
void get_drive_type( DRIVE_BAR *dbar)
{
char tmp[ MAX_LINE];
char *s;
/**
Check passwd file to see if *dbar->path belong to a user account.
**/
if ( strcmp( dbar->path, "/") != 0) {
struct passwd *pw_field;
setpwent();
while(( pw_field = getpwent()) != NULL) {
if ( strcmp( pw_field->pw_dir, dbar->name) == 0) {
dbar->userid = pw_field->pw_uid;
dbar->type = USER;
return;
}
}
}
strcpy( tmp, dbar->dev);
s = tmp;
while ( *s)
*s++ = tolower( *s);
if ( strchr( tmp, ':') != NULL || strchr( tmp, '@') != NULL)
dbar->type = NETWORK_DISK;
else if ( searchfor( tmp, "cdrom"))
dbar->type = CDROM;
else if ( searchfor( tmp, "floppy"))
dbar->type = FLOPPY_DISK;
else
dbar->type = HARD_DISK;
}
char *readlink_path( char *path)
{
char tmp[ MAX_LINE];
char tmp2[ MAX_LINE];
char newpath[ MAX_LINE];
char *s1, *s2, *s3;
int lstring;
strcpy( tmp, path);
if ( *tmp != '/')
if ( getcwd( tmp2, MAX_LINE) != NULL) {
sprintf( newpath, "%s/%s", tmp2, tmp);
strcpy( tmp, newpath);
}
strcpy( newpath, "/");
s1 = tmp;
while (( s2 = strchr( s1 + 1, '/')) != NULL) {
*s2 = '\0';
sprintf( tmp2, "%s%s", newpath, s1);
if (( lstring = readlink( s1, tmp2, MAX_LINE)) > 0) {
*( tmp2 + lstring) = '\0';
if ( *tmp2 == '.') {
s3 = strrchr( newpath, '/');
*( s3 + 1) = '\0';
sprintf( tmp, "%s%s/", newpath, tmp2);
} else {
sprintf( newpath, "%s/", tmp2);
}
} else {
sprintf( newpath, "%s%s/", newpath, s1 + 1);
}
s1 = s2;
}
sprintf( newpath, "%s%s", newpath, s1 + 1);
if (( lstring = readlink( newpath, tmp2, MAX_LINE)) > 0) {
*( tmp2 + lstring) = '\0';
if ( *tmp2 == '.') {
s3 = strrchr( newpath, '/');
*( s3 + 1) = '\0';
sprintf( tmp, "%s%s", newpath, tmp2);
path = strdup( tmp);
} else {
path = strdup( tmp2);
}
} else if ( strcmp( newpath, path) != 0)
path = strdup( newpath);
else
path = strdup( path);
if ( *path != '/') {
sprintf( tmp, "/%s", path);
free( path);
path = strdup( tmp);
}
return( path);
}
void getfsinfo( DRIVE_BAR *dbar)
{
#ifdef SOLARIS
struct statvfs sb;
#else
struct statfs sb;
#endif
unsigned long bfree, bsize;
#if defined(DIGITAL_UNIX)
statfs( dbar->path, &sb);
bfree = sb.f_bavail;
bsize = sb.f_fsize;
#elif defined(SGI) || defined(SCO)
statfs( dbar->path, &sb, sizeof(struct statfs), 0);
bfree = sb.f_bfree;
bsize = sb.f_bsize;
#if defined(SCO)
/* Dunno why this is necesary but it is otherwise stats are wrong by a
* factor of 2 (bsize = 1024 ) - suspect one of the blocksize or
* block numbers returned are bogus...
* Note I've limited this to HTFS but may also be necessary for
* other FS as well
* Hops 22-Jun-95
*/
if (sb.f_fstyp == 5 ) /* HTFS */
{
if ( bsize > 512 ) bsize = 512 ;
}
#endif
#elif defined (SOLARIS)
statvfs( dbar->path, &sb);
bfree = sb.f_bavail;
bsize = sb.f_frsize;
#else
statfs( dbar->path, &sb);
bfree = sb.f_bavail;
bsize = sb.f_bsize;
#endif
#ifdef HAVE_QUOTAS
if ( dbar->type == USER) {
struct dqblk qd;
#if defined(AIX)
if ( quotactl( dbar->path, Q_GETQUOTA, dbar->userid, (char *) &qd) == 0) {
#elif defined(SGI) || defined(SUNOS)
if ( quotactl( Q_GETQUOTA, dbar->dev, dbar->userid, (char *) &qd) == 0) {
#elif defined(SOLARIS)
if ( quotactl( Q_GETQUOTA, dbar->path, dbar->userid, &qd) == 0) {
#else
if ( quotactl( Q_GETQUOTA, dbar->dev, dbar->userid, (char *) &qd) == 0) {
#endif
if ( qd.dqb_bhardlimit != 0 &&
( qd.dqb_bhardlimit - qd.dqb_curblocks) < bfree) {
if ( Resrcs.show_diskused)
dbar->mbytes =
(float)(qd.dqb_curblocks) *
(float)(bsize) / 1048576.0;
else
dbar->mbytes =
(float)(qd.dqb_bhardlimit - qd.dqb_curblocks) *
(float)(bsize) / 1048576.0;
dbar->usage = 100 * qd.dqb_curblocks /
qd.dqb_bhardlimit;
dbar->usage_type = QUOTA_SPACE;
return;
}
} else if ( Resrcs.verbose)
fprintf( stderr, "Error %d on quotas for device \"%s\" at \"%s\"\n",
errno, dbar->dev, dbar->path);
}
#endif /** HAVE_QUOTAS **/
if ( Resrcs.show_diskused)
dbar->mbytes = (float)(sb.f_blocks - bfree) *
(float)(bsize) / 1048576.0;
else
dbar->mbytes = (float)(bfree) * (float)(bsize) / 1048576.0;
dbar->usage =
(sb.f_blocks > 0) ? 100 * (sb.f_blocks - bfree) / sb.f_blocks : 0;
dbar->usage_type = SYSTEM_SPACE;
}
#ifdef USE_IOCTL
/*
* Thanks to Davin Milun for Solaris 2.x support. Email: milun@cs.buffalo.edu.
* He explaines the following:
*
* Define the "quotactl" function as in Solaris 1, based on ioctl().
* By Marc Mazuhelli <mazu@dmi.usherb.ca>
* The "special" parameter is any file (even the root) on the file system,
* not the block special device name as in Solaris 1.
* Thanks to veronica@solution.maths.unsw.edu.au who provided
* the idea and the basis for this function.
*/
int quotactl(int cmd, char *special, uid_t uid, struct dqblk * addr)
{
struct quotctl op;
int fd = open(special, O_RDONLY);
if ( fd < 0)
return -1;
op.op = cmd;
op.uid = uid;
op.addr = (caddr_t) addr;
if (ioctl(fd, Q_QUOTACTL, &op) < 0) {
close(fd);
return -1;
}
close(fd);
return (0);
}
#endif /* USE_IOCTL */
void check_args( int nargs, char **argv)
{
while ( --nargs)
if ( strcmp( *++argv, "-t") == 0)
Resrcs.show_titlebar = False;
}
/**
fatal: prints an error message and terminates program.
**/
void fatal( char *fmt, ...)
{
va_list args;
va_start( args, fmt);
fprintf( stderr, "%s:", progname);
vfprintf( stderr, fmt, args);
putc( '\n', stderr);
va_end( args);
exit( 1);
}
/**
warning: prints an warning message.
**/
void warning( char *fmt, ...)
{
va_list args;
va_start( args, fmt);
fprintf( stderr, "%s:", progname);
vfprintf( stderr, fmt, args);
putc( '\n', stderr);
va_end( args);
}
/**
fget_line: get a line of characters from file fp
**/
int fget_line( char *s, int lim, FILE *fp)
{
if ( fgets( s, lim, fp) == NULL)
return ( EOF);
else {
s[ strlen( s) - 1] = '\0';
return( strlen( s));
}
}
/**
searchfor: Searchs for a string within another string.
**/
int searchfor( char *string, char *test)
{
char *s;
int ltest;
ltest = strlen( test);
s = string;
while (( s = strchr( s, *test)) != NULL) {
if ( strlen( s) >= ltest)
if ( strncmp( s, test, ltest) == 0)
return( True);
++s;
}
return( False);
}